home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Programming / FreshBar / Source / WindowList.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-29  |  22.6 KB  |  969 lines

  1. //*************************************************************************//
  2. // Filename:    WindowList.cpp
  3. // Autor:       Christian Taulien of Strange Intelligence
  4. // Purpose:     Window management implementation for FreshBar
  5. // Creation:    17. Mai 1998
  6. //*************************************************************************//
  7.  
  8. #include <exec/types.h>
  9. #include <exec/nodes.h>
  10. #include <exec/lists.h>
  11. #include <exec/ports.h>
  12. #include <intuition/intuition.h>
  13. #include <libraries/gadtools.h>
  14.  
  15. #include <clib/exec_protos.h>
  16. #include <clib/intuition_protos.h>
  17. #include <clib/gadtools_protos.h>
  18. #include <clib/graphics_protos.h>
  19. #include <clib/utility_protos.h>
  20. #include <clib/dos_protos.h>
  21.  
  22. #include "WindowList.h"
  23. #include "VisualInfo.h"
  24. #include "TextMeasure.h"
  25. #include "global.h"
  26.  
  27. extern "C" void NewList(struct List *list);
  28.  
  29. void StripIntuiMessages(struct MsgPort *arg_poMsgPort, struct Window *arg_poWindow)
  30. /*S*/
  31. /*S*/ /* Methoden-Rahmen */
  32. /*************************************************************************
  33. * Name der Methode: ::StripIntuiMessages()
  34. *
  35. * Klasse: --
  36. *
  37. * Funktion:
  38. *   function to remove and reply all IntuiMessages on a port that have been
  39. *   sent to a particular window (note that we don't rely on the ln_Succ
  40. *   pointer of a message after we have replied it)
  41. *
  42. * Zugriff: public
  43. *
  44. * Eingabe-Parameter: 2
  45. *   arg_poMsgPort:  Zeiger auf den Messageport (UserPort) des Fensters
  46. *   arg_poWindow:   Zeiger auf das Fenster um das es dabei geht.
  47. *
  48. * Ausgabe-Parameter: -
  49. *
  50. * Aufgerufen von: -
  51. *
  52. * Verwendung folgender globaler Variablen/Strukturen: -
  53. *
  54. * Benutzte Methoden: 2
  55. *   exec.library/Remove()
  56. *   exec.library/ReplyMsg()
  57. *
  58. * Version: 1.0
  59. *
  60. * Autor: RKRM Libraries
  61. *
  62. * Datum: 17. Mai 1998
  63. *
  64. * Letzte Änderungen/Neuerungen:
  65. * 17. Mai 1998: Methode definiert
  66. *
  67. *************************************************************************/
  68. /*E*/
  69. {
  70.   struct IntuiMessage *poMsg = (struct IntuiMessage *)arg_poMsgPort->mp_MsgList.lh_Head;
  71.  
  72.   struct Node *succ;
  73.   while (succ = poMsg->ExecMessage.mn_Node.ln_Succ)
  74.   {
  75.     if (poMsg->IDCMPWindow == arg_poWindow)
  76.     {
  77.       // Intuition is about to free this message.
  78.       // Make sure that we have politely sent it back.
  79.       Remove((struct Node *) poMsg);
  80.  
  81.       ReplyMsg((struct Message *) poMsg);
  82.     } // if
  83.     poMsg = (struct IntuiMessage *) succ;
  84.   } // while
  85. } // StripIntuiMessages()
  86. /*E*/
  87. void CloseWindowSafely(struct Window *arg_poWindow)
  88. /*S*/
  89. /*S*/ /* Methoden-Rahmen */
  90. /*************************************************************************
  91. * Name der Methode: ::CloseWindowSafely()
  92. *
  93. * Klasse: --
  94. *
  95. * Funktion:
  96. *   Strip all IntuiMessages from an IDCMP which are waiting for a specific
  97. *   window.  When the messages are gone, set the UserPort of the window to
  98. *   NULL and call ModifyIDCMP(win,0).  This will free the Intuition arts
  99. *   of the IDMCMP and trun off message to this port without changing the
  100. *   original UserPort (which may be in use by other windows).
  101. *
  102. * Zugriff: public
  103. *
  104. * Eingabe-Parameter: 1
  105. *   arg_poWindow: Zeiger auf das Fenster
  106. *
  107. * Ausgabe-Parameter:
  108. *
  109. * Aufgerufen von:
  110. *
  111. * Verwendung folgender globaler Variablen/Strukturen:
  112. *
  113. * Benutzte Methoden: 5
  114. *   exec.library/Forbid()
  115. *   exec.library/Permit()
  116. *   intuition.library/ModifyIDCMP()
  117. *   intuition.library/CloseWindow()
  118. *   StripIntuiMessages()
  119. *
  120. * Version: 1.0
  121. *
  122. * Autor: RKRM Libraries
  123. *
  124. * Datum: 17. Mai 1998
  125. *
  126. * Letzte Änderungen/Neuerungen:
  127. * 17. Mai 1998: Methode definiert / RKRM-Libraries
  128. *
  129. *************************************************************************/
  130. /*E*/
  131. {
  132.   TRACE("Entry");
  133.   // if no valid window-pointer
  134.   if (!arg_poWindow)
  135.   {
  136.     return;
  137.   } // if
  138.  
  139.   // we forbid here to keep out of race conditions with Intuition
  140.   Forbid();
  141.  
  142.   // send back any messages for this window  that have not yet been processed
  143.   StripIntuiMessages(arg_poWindow->UserPort, arg_poWindow);
  144.  
  145.   // clear UserPort so Intuition will not free it
  146.   arg_poWindow->UserPort = NULL;
  147.  
  148.   // tell Intuition to stop sending more messages
  149.   ModifyIDCMP(arg_poWindow, 0L);
  150.  
  151.   // turn multitasking back on
  152.   Permit();
  153.  
  154.   // Now it's safe to really close the window
  155.   CloseWindow(arg_poWindow);
  156. } // CloseWindowSafely()
  157. /*E*/
  158. char getShortCut(char *arg_sString)
  159. /*S*/
  160. {
  161.   TRACE("Entry");
  162.   char cShortCut = '\0';
  163.  
  164.   // wenn string gefunden
  165.   if (arg_sString)
  166.   {
  167.     int iLen = strlen(arg_sString);
  168.     for (int i=0; i<iLen; ++i)
  169.     {
  170.       // wenn underscore gefunden und noch min. ein zeichen danach
  171.       // vorhanden
  172.       if (arg_sString[i] == '_' && (i < iLen-1))
  173.       {
  174.         // shortcut gefunden. Schleife verlassen
  175.         cShortCut = arg_sString[i+1];
  176.         break;
  177.       } // if
  178.     } // for
  179.   } // if
  180.  
  181. return ToLower(cShortCut);
  182. }
  183. /*E*/
  184.  
  185. //******************************************************************//
  186. //******************************************************************//
  187. //
  188. //  BarWindowNodeC
  189. //
  190. //******************************************************************//
  191. //******************************************************************//
  192. ULONG BarWindowNodeC::m_ulNextFreeID = 0;
  193.  
  194. BarWindowNodeC::BarWindowNodeC(BarWindowListC *arg_poBarWindowList,
  195.                                char *arg_sName,
  196.                                char *arg_sButtonName,
  197.                                char *arg_sScreenName,
  198.                                BOOL arg_bCloseGadget)
  199. /*S*/
  200. {
  201.   TRACE("Konstruktor");
  202.   if (!arg_poBarWindowList)
  203.   {
  204.     TRACE("Falscher Parameter!");
  205.     throw;
  206.   } // if
  207.  
  208.   // init the baseclassmembers
  209.   ln_Succ       = NULL;
  210.   ln_Pred       = NULL;
  211.   ln_Type       = NT_USER;
  212.   ln_Pri        = 0;
  213.  
  214.   // now our members
  215.   m_oName              = arg_sName;
  216.   m_oButtonText        = arg_sButtonName;
  217.   m_poLockedScreen     = NULL;
  218.   m_poBarWindow        = NULL;
  219.   m_oScreenName        = arg_sScreenName;
  220.   m_bGadgetsAttached   = FALSE;
  221.   m_bCloseGadget       = arg_bCloseGadget;
  222.   m_poSharedUserPort   = arg_poBarWindowList->getSharedUserPort();
  223.   m_ulBarWindowID      = ++m_ulNextFreeID;
  224.   m_iWidth             = 150;
  225.   m_iHeight            = 100;
  226.   m_iTop               = 100;
  227.   m_iLeft              = 100;
  228.   m_iBorderTop         = 4;
  229.   m_iBorderLeft        = 4;
  230.   m_iBorderBottom      = 4;
  231.   m_iBorderRight       = 4;
  232.   m_iMaxVisibleEntries = 15;
  233.   m_poFirstGadget      = NULL;
  234.   m_poButton           = NULL;
  235.  
  236.   AddTail(arg_poBarWindowList, this);
  237. } // BarWindowNodeC::BarWindowNodeC()
  238. /*E*/
  239. BarWindowNodeC::~BarWindowNodeC()
  240. /*S*/
  241. {
  242.   TRACE("Destruktor");
  243.  
  244.   // delete the window
  245.   if (m_poBarWindow)
  246.   {
  247.     closeBarWindow();
  248.   } // if
  249.  
  250.   // delete the name
  251.   if (ln_Name)
  252.   {
  253.     delete ln_Name;
  254.   } // if
  255.  
  256.   // if the node is in a list
  257.   if (ln_Pred && ln_Succ)
  258.   {
  259.     Remove(this);
  260.   } // if
  261. }
  262. /*E*/
  263. struct Screen *BarWindowNodeC::lockScreen()
  264. /*S*/
  265. {
  266.   TRACE("Entry");
  267.   if (m_poLockedScreen)
  268.   {
  269.     TRACE("Screen already locked!");
  270.     return m_poLockedScreen;
  271.   } //
  272.  
  273.   // lock the wanted screen
  274.   if (m_oScreenName.isEmpty())
  275.   {
  276.     m_poLockedScreen = LockPubScreen(NULL);
  277.   }
  278.   else
  279.   {
  280.     m_poLockedScreen = LockPubScreen(m_oScreenName);
  281.   } // if
  282.  
  283. return m_poLockedScreen;
  284. }
  285. /*E*/
  286. void BarWindowNodeC::unlockScreen()
  287. /*S*/
  288. {
  289.   TRACE("Entry");
  290.   // wenn wir einen public screen gelockt haben.
  291.   if (m_poLockedScreen)
  292.   {
  293.     UnlockPubScreen(NULL, m_poLockedScreen);
  294.     m_poLockedScreen = NULL;
  295.   } // if
  296. }
  297. /*E*/
  298. BOOL BarWindowNodeC::openBarWindow()
  299. /*S*/
  300. {
  301.   TRACE("Entry");
  302.  
  303. BOOL erfolg = FALSE;
  304.   // wenn das Fenster schon offen ist
  305.   if (isOpen())
  306.   {
  307.     TRACE("schon offen");
  308.     // dann nur aktivieren und zurückkehren
  309.     ActivateWindow(m_poBarWindow);
  310.     WindowToFront(m_poBarWindow);
  311.     return TRUE;
  312.   } // if
  313.  
  314.   // Wenn wir eine Bar-Liste haben.
  315.   TRACE("Bars vorhanden");
  316.   lockScreen();
  317.  
  318.   validateWindowSize();
  319.   setBarWindowPos(-1,-1);
  320.   createGadgets();
  321.  
  322.   if (m_poBarWindow = OpenWindowTags(NULL,
  323.         WA_Width, m_iWidth,
  324.         WA_Height, m_iHeight,
  325.         WA_AutoAdjust, TRUE,
  326.         WA_Top, m_iTop,
  327.         WA_Left, m_iLeft,
  328.         WA_PubScreen, m_poLockedScreen,
  329.         WA_Activate, TRUE,
  330.         WA_DragBar, TRUE,
  331.         WA_DepthGadget, TRUE,
  332.         WA_CloseGadget, m_bCloseGadget,
  333.         WA_SizeGadget, FALSE,
  334.         WA_SmartRefresh, TRUE,
  335.         WA_RMBTrap, TRUE,
  336.         WA_IDCMP, NULL,
  337.         WA_Title, (char *) m_oName,
  338.         TAG_DONE))
  339.   {
  340.     TRACE("Fenster ist jetzt offen");
  341.     m_poBarWindow->UserPort = m_poSharedUserPort;
  342.     ModifyIDCMP(m_poBarWindow,   CLOSEWINDOW
  343.                                | REFRESHWINDOW
  344.                                | BUTTONIDCMP
  345.                                | IDCMP_VANILLAKEY
  346.                                | IDCMP_RAWKEY);
  347.     m_poBarWindow->UserData = (char *) this;
  348.     showGadgets();
  349.     erfolg = TRUE;
  350.   } // if
  351. return erfolg;
  352. }
  353. /*E*/
  354. void BarWindowNodeC::closeBarWindow()
  355. /*S*/
  356. {
  357.   TRACE("Entry");
  358.   m_iLeft = m_poBarWindow->LeftEdge;
  359.   m_iTop = m_poBarWindow->TopEdge;
  360.  
  361.   hideGadgets();
  362.   CloseWindowSafely(m_poBarWindow);
  363.   unlockScreen();
  364.   m_poBarWindow = NULL;
  365.  
  366.   freeGadgets();
  367. }
  368. /*E*/
  369. void BarWindowNodeC::setBarWindowTitle(char *arg_sName)
  370. /*S*/
  371.   TRACE("Entry");
  372.   m_oName = arg_sName;
  373.   if (isOpen())
  374.   {      
  375.     SetWindowTitles(m_poBarWindow, arg_sName, (char *) ~0);
  376.   } // if
  377. }
  378. /*E*/
  379. struct Gadget *BarWindowNodeC::createGadgets()
  380. /*S*/
  381. {
  382.   TRACE("Entry");
  383.  
  384.   // if no button needed
  385.   if (!hasButton())
  386.   {
  387.     return NULL;
  388.   } // if
  389.  
  390.   // Rückgabe
  391.   struct Gadget *pGad = NULL;
  392.  
  393.   // parameter-check
  394.   if (!m_poLockedScreen)
  395.   {
  396.     TRACE("Wrong createGadgets()-Parameter!");
  397.     return pGad;
  398.   } // if
  399.  
  400.   VisualInfoC oVI(m_poLockedScreen);
  401.   if (!oVI)
  402.   {
  403.     TRACE("VisualInfo failed");
  404.     return pGad;
  405.   } // if
  406.  
  407.   // für Gadtools erforderlich
  408.   pGad = CreateContext(&m_poFirstGadget);
  409.   if (pGad)
  410.   {
  411.     TRACE("CreateContext ok");
  412.  
  413.     // ermittle die Hoehe der Balken
  414.     int iHeightOfBars = m_oBarList.getHeight(m_poLockedScreen);
  415.  
  416.     TextMeasureC oTeMe(m_poLockedScreen);
  417.     struct NewGadget ng;
  418.     ng.ng_Width      = oTeMe.getTextWidth(m_oButtonText) + 10;
  419.     ng.ng_Height     = oTeMe.getTextHeight() + 6;
  420.     ng.ng_TopEdge    = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + iHeightOfBars + oTeMe.getTextHeight() + m_iBorderTop;
  421.  
  422.     // breite und hoehe des Fensters neu anpassen
  423.     m_iHeight = ng.ng_TopEdge + ng.ng_Height + m_poLockedScreen->WBorBottom+4;
  424.     if (ng.ng_Width > m_iWidth - m_poLockedScreen->WBorLeft - m_poLockedScreen->WBorRight - 20)
  425.     {
  426.       m_iWidth = ng.ng_Width + m_poLockedScreen->WBorLeft + m_poLockedScreen->WBorRight + 20;
  427.     } // if
  428.     ng.ng_LeftEdge   = (m_iWidth-oTeMe.getTextWidth(m_oButtonText) - 10)/2;
  429.     ng.ng_GadgetText = (char *) m_oButtonText;
  430.     ng.ng_TextAttr   = m_poLockedScreen->Font;
  431.     ng.ng_Flags      = PLACETEXT_IN;
  432.     ng.ng_GadgetID   = 42;
  433.     ng.ng_UserData   = NULL;
  434.     ng.ng_VisualInfo = oVI;
  435.     // Das Weiter-Gadget jetzt erstellen
  436.     m_poButton = pGad = CreateGadget(BUTTON_KIND, pGad, &ng,
  437.         GT_Underscore, '_',
  438.         TAG_DONE);
  439.     if (pGad)
  440.     {
  441.       TRACE("Gadgets ok");
  442.     } // if
  443.   } // if
  444. return pGad;
  445. }
  446. /*E*/
  447. void BarWindowNodeC::freeGadgets()
  448. /*S*/
  449. {
  450.   TRACE("Entry");
  451.   // if no button needed
  452.   if (!hasButton())
  453.   {
  454.     return;
  455.   } // if
  456.  
  457.   // wenn das Fenster noch offen ist
  458.   if (m_poBarWindow)
  459.   {
  460.     // die gadget vorher removen
  461.     hideGadgets();
  462.   } // if
  463.  
  464.   // wenn die gadget "befreit" werden müssen
  465.   if (m_poFirstGadget)
  466.   {
  467.     FreeGadgets(m_poFirstGadget);
  468.     m_poFirstGadget = NULL;
  469.     m_poButton = NULL;
  470.   } // if
  471. }
  472. /*E*/
  473. void BarWindowNodeC::clearBarWindow()
  474. /*S*/
  475. {
  476.   TRACE("Entry");
  477.   // wenn Fenster offen
  478.   if (isOpen())
  479.   {
  480.     EraseRect(m_poBarWindow->RPort,
  481.               m_poBarWindow->BorderLeft,
  482.               m_poBarWindow->BorderTop,
  483.               m_poBarWindow->Width-m_poBarWindow->BorderRight-1,
  484.               m_poBarWindow->Height-m_poBarWindow->BorderBottom-1);
  485.  
  486.   } // if
  487. }
  488. /*E*/
  489. void BarWindowNodeC::hideGadgets()
  490. /*S*/
  491. {
  492.   TRACE("Entry");
  493.  
  494.   // if no button needed
  495.   if (!hasButton())
  496.   {
  497.     return;
  498.   } // if
  499.  
  500.   // validation check
  501.   if (!m_poBarWindow || !m_poFirstGadget)
  502.   {
  503.     TRACE("Falsche Parameter");
  504.     return;
  505.   } // if
  506.  
  507.   if (!m_bGadgetsAttached)
  508.   {
  509.     TRACE("Gadgets garnicht attached");
  510.     return;
  511.   } // if
  512.   RemoveGList(m_poBarWindow, m_poFirstGadget, ~0);
  513.  
  514.   m_bGadgetsAttached = FALSE;
  515. }
  516. /*E*/
  517. void BarWindowNodeC::showGadgets()
  518. /*S*/
  519. {
  520.   TRACE("Entry");
  521.  
  522.   clearBarWindow();
  523.   m_oBarList.drawBars(this,
  524.                       m_poLockedScreen->WBorLeft + m_iBorderLeft,
  525.                       m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + m_iBorderTop);
  526.  
  527.   // if no button needed
  528.   if (m_oButtonText.isEmpty())
  529.   {
  530.     return;
  531.   } // if
  532.  
  533.   // validation check
  534.   if (!m_poBarWindow || !m_poFirstGadget)
  535.   {
  536.     TRACE("Falsche Parameter");
  537.     return;
  538.   } // if
  539.  
  540.   // wenn das Fenster bereits Gadgets hat
  541.   if (m_bGadgetsAttached)
  542.   {
  543.     TRACE("Gadgets bereits vorhanden");
  544.     return;
  545.   } // if
  546.  
  547.   AddGList(m_poBarWindow, m_poFirstGadget, -1, -1, NULL);
  548.   RefreshGList(m_poFirstGadget, m_poBarWindow, NULL, -1);
  549.   GT_RefreshWindow(m_poBarWindow, NULL);
  550.  
  551.   VisualInfoC oVI(m_poBarWindow);
  552.   if (oVI.isOk())
  553.   {
  554.     TRACE("Visualinfo ok");
  555.     //int width = m_poBarWindow->Width - m_poBarWindow->WScreen->WBorLeft - m_poBarWindow->WScreen->WBorLeft - 8;
  556.     int width = m_poBarWindow->Width - m_poLockedScreen->WBorLeft - m_poLockedScreen->WBorRight - m_iBorderLeft - m_iBorderRight;
  557.     int top = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + m_iBorderTop;
  558.         top += m_oBarList.getSize() * (m_poBarWindow->WScreen->Font->ta_YSize + 6);
  559.  
  560.     DrawBevelBox( m_poBarWindow->RPort,
  561.                   m_poLockedScreen->WBorLeft + m_iBorderLeft,
  562.                   top + 6,
  563.                   width,
  564.                   2,
  565.                   GT_VisualInfo, (APTR) oVI,
  566.                   GTBB_Recessed, TRUE,
  567.                   TAG_DONE );
  568.   } // if
  569.  
  570.   m_bGadgetsAttached = TRUE;
  571. }
  572. /*E*/
  573. void BarWindowNodeC::validateWindowSize()
  574. /*S*/
  575.   TRACE("Entry");
  576.   setBarWindowWidth(m_iWidth);
  577. }
  578. /*E*/
  579. void BarWindowNodeC::setBarWindowWidth(ULONG arg_ulWidth)
  580. /*S*/
  581. {
  582.   TRACE("Entry");
  583.   // wenn das fenster offen ist
  584.   if (isOpen())
  585.   {
  586.     hideGadgets();
  587.     int iBarTitleWidth = m_oBarList.getBarTitleWidth(m_poLockedScreen)
  588.                        + m_poLockedScreen->WBorLeft
  589.                        + m_poLockedScreen->WBorRight
  590.                        + m_iBorderLeft
  591.                        + m_iBorderRight;
  592.     m_iWidth = SIFC_MAX(arg_ulWidth, 50 + iBarTitleWidth);
  593.     m_oBarList.setBarWidth(m_iWidth - iBarTitleWidth);
  594.     TextMeasureC oTeMe(m_poLockedScreen);
  595.     int iHeightOfBars = m_oBarList.getHeight(m_poLockedScreen);
  596.     if (m_poButton)
  597.     {
  598.       m_poButton->LeftEdge = (m_iWidth-oTeMe.getTextWidth(m_oButtonText) - 10)/2;
  599.       m_poButton->TopEdge  = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + iHeightOfBars + oTeMe.getTextHeight() + m_iBorderTop;
  600.       m_iHeight = m_poButton->TopEdge + m_poButton->Height + m_poLockedScreen->WBorBottom+4;
  601.     }
  602.     else
  603.     {
  604.       m_iHeight = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + iHeightOfBars + m_poLockedScreen->WBorBottom+7;
  605.     } // if
  606.  
  607.     ChangeWindowBox(m_poBarWindow,
  608.                     m_poBarWindow->LeftEdge,
  609.                     m_poBarWindow->TopEdge,
  610.                     m_iWidth,
  611.                     m_iHeight);
  612.     Delay(5);
  613.     showGadgets();
  614.   }
  615.   else
  616.   {
  617.     m_iWidth = arg_ulWidth;
  618.     if (m_poLockedScreen)
  619.     {
  620.       int iBarTitleWidth = m_oBarList.getBarTitleWidth(m_poLockedScreen)
  621.                          + m_poLockedScreen->WBorLeft
  622.                          + m_poLockedScreen->WBorRight
  623.                          + m_iBorderLeft
  624.                          + m_iBorderRight;
  625.       m_iWidth = SIFC_MAX(arg_ulWidth, 50 + iBarTitleWidth);
  626.       m_oBarList.setBarWidth(m_iWidth - iBarTitleWidth);
  627.       TextMeasureC oTeMe(m_poLockedScreen);
  628.       int iHeightOfBars = m_oBarList.getHeight(m_poLockedScreen);
  629.       if (m_poButton)
  630.       {
  631.         m_poButton->LeftEdge = (m_iWidth-oTeMe.getTextWidth(m_oButtonText) - 10)/2;
  632.         m_poButton->TopEdge  = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + iHeightOfBars + oTeMe.getTextHeight() + m_iBorderTop;
  633.       }
  634.       else
  635.       {
  636.         m_iHeight = m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + iHeightOfBars + m_poLockedScreen->WBorBottom+7;
  637.       } // if
  638.     } // if
  639.   } // if
  640. }
  641. /*E*/
  642. void BarWindowNodeC::setBarWindowPos(int arg_iPosX, int arg_iPosY)
  643. /*S*/
  644. {
  645.   TRACE("Entry");
  646.   if (!m_poLockedScreen)
  647.   {
  648.     return;
  649.   } // if
  650.  
  651.   switch (arg_iPosX)
  652.   {
  653.     case -1:
  654.       m_iLeft = (m_poLockedScreen->Width - m_iWidth)/2;
  655.       break;
  656.     case -2:
  657.       break;
  658.     default:
  659.       m_iLeft = arg_iPosX;
  660.       break;
  661.   } // switch
  662.  
  663.   switch (arg_iPosY)
  664.   {
  665.     case -1:
  666.       m_iTop = (m_poLockedScreen->Height - m_iHeight)/2;
  667.       break;
  668.     case -2:
  669.       break;
  670.     default:
  671.       m_iTop = arg_iPosY;
  672.       break;
  673.   } // switch
  674.  
  675.   if (isOpen())
  676.   {
  677.     ChangeWindowBox(m_poBarWindow,
  678.                     m_iLeft,
  679.                     m_iTop,
  680.                     m_poBarWindow->Width,
  681.                     m_poBarWindow->Height);
  682.   } // if
  683. }
  684. /*E*/
  685. void BarWindowNodeC::refreshBars()
  686. /*S*/
  687. {
  688.   TRACE("Entry");
  689.   if (!isOpen())
  690.   {
  691.     return;
  692.   } // if
  693.  
  694.   m_oBarList.fillBars(this,
  695.                       m_poLockedScreen->WBorLeft + m_iBorderLeft,
  696.                       m_poLockedScreen->WBorTop + m_poLockedScreen->BarHeight + m_iBorderTop);
  697. }
  698. /*E*/
  699. BarNodeC *BarWindowNodeC::addBar(char *arg_sName, ULONG arg_ulMaxValue)
  700. /*S*/
  701. {
  702.   TRACE("Entry");
  703.   BarNodeC *poNode = m_oBarList.addBar(arg_sName, arg_ulMaxValue);
  704.   validateWindowSize();
  705. return poNode;
  706. }
  707. /*E*/
  708. void BarWindowNodeC::removeBar(ULONG arg_ulBarID)
  709. /*S*/
  710. {
  711.   TRACE("Entry");
  712.   m_oBarList.removeBar(arg_ulBarID);
  713.   validateWindowSize();
  714. }
  715. /*E*/
  716. BOOL BarWindowNodeC::testOKButton()
  717. /*S*/
  718.   TRACE("Entry");
  719.   // if no valid window-pointer
  720.   if (!isOpen())
  721.   {
  722.     return FALSE;
  723.   } // if
  724.  
  725.   BOOL bOk = FALSE;
  726.   // we forbid here to keep out of race conditions with Intuition
  727.   Forbid();
  728.  
  729.   // send back any messages for this window  that have not yet been processed
  730.   struct IntuiMessage *poMsg = (struct IntuiMessage *)m_poBarWindow->UserPort->mp_MsgList.lh_Head;
  731.  
  732.   struct Node *succ;
  733.   while (succ = poMsg->ExecMessage.mn_Node.ln_Succ)
  734.   {
  735.     if (poMsg->IDCMPWindow == m_poBarWindow)
  736.     {
  737.       // Intuition is about to free this message.
  738.       // Make sure that we have politely sent it back.
  739.       Remove((struct Node *) poMsg);
  740.  
  741.       ULONG ulClass = ((struct IntuiMessage *) poMsg)->Class;
  742.       switch (ulClass)
  743.       {
  744.         case IDCMP_GADGETUP:
  745.         case IDCMP_CLOSEWINDOW:
  746.           bOk = TRUE;
  747.           break;
  748.         case IDCMP_VANILLAKEY:
  749.           char cKey = (char) ((struct IntuiMessage *) poMsg)->Code;
  750.           if ((cKey == 27) || (ToLower(cKey) == ::getShortCut(m_oButtonText)))
  751.           {
  752.             bOk = TRUE;
  753.           } // if
  754.           break;
  755.       } // switch
  756.  
  757.       ReplyMsg((struct Message *) poMsg);
  758.     } // if
  759.     poMsg = (struct IntuiMessage *) succ;
  760.   } // while
  761.  
  762.   // turn multitasking back on
  763.   Permit();
  764.  
  765. return bOk;
  766. }
  767. /*E*/
  768. BarWindowNodeC *BarWindowNodeC::getNext(void)
  769. /*S*/
  770. {
  771.   TRACE("getNext()");
  772.   if (ln_Succ && ln_Succ->ln_Succ)
  773.   {
  774.     return (BarWindowNodeC *) ln_Succ;
  775.   } // if
  776.  
  777. return NULL;
  778. }
  779. /*E*/
  780. BarWindowNodeC *BarWindowNodeC::getPrev(void)
  781. /*S*/
  782. {
  783.   TRACE("getPrev()");
  784.   if (ln_Pred && ln_Pred->ln_Pred)
  785.   {
  786.     return (BarWindowNodeC *) ln_Pred;
  787.   } // if
  788.  
  789. return NULL;
  790. }
  791. /*E*/
  792.  
  793. //******************************************************************//
  794. //******************************************************************//
  795. //
  796. //  BarWindowListC
  797. //
  798. //******************************************************************//
  799. //******************************************************************//
  800. BarWindowListC::BarWindowListC()
  801. /*S*/
  802. {
  803.   TRACE("Konstruktor");
  804.   NewList(this);
  805.   m_poSharedUserPort = CreateMsgPort();
  806. } // BarWindowListC::BarWindowListC()
  807. /*E*/
  808. BarWindowListC::~BarWindowListC()
  809. /*S*/
  810. {
  811.   TRACE("Destruktor");
  812.   removeAll();
  813.  
  814.   // delete the port created in the constructor
  815.   if (m_poSharedUserPort)
  816.   {  
  817.     DeleteMsgPort(m_poSharedUserPort);
  818.   } // if
  819. } // BarWindowListC::~FLXWacthListC()
  820. /*E*/
  821. void BarWindowListC::removeAll()
  822. /*S*/
  823. {
  824.   TRACE("Entry");
  825.   // wenn die Liste nicht leer ist
  826.   if (!IsListEmpty(this))
  827.   {
  828.     BarWindowNodeC *poNode;
  829.     while (poNode = (BarWindowNodeC *) RemHead(this))
  830.     {
  831.       // Vorgaenger und Nachfolger auf null setzen
  832.       // weil mit RemHead schon removed und der Destruktor
  833.       // das bei nicht nulligen nodes nochmal machen wuerde.
  834.       poNode->ln_Succ = NULL;
  835.       poNode->ln_Pred = NULL;
  836.       delete poNode;
  837.     } // while
  838.   } // if
  839.   NewList(this);
  840. }
  841. /*E*/
  842. void BarWindowListC::removeBarWindow(ULONG arg_ulBarWindowID)
  843. /*S*/
  844.   TRACE("Entry");
  845.   // just find the node an delete it
  846.   BarWindowNodeC *poNode = findBarWindowNode(arg_ulBarWindowID);
  847.   if (poNode)
  848.   {
  849.     delete poNode;
  850.   } // if
  851. }
  852. /*E*/
  853. BarWindowNodeC *BarWindowListC::addBarWindow(char *arg_sName, char *arg_sButtonName, char *arg_sScreenName, BOOL arg_bCloseGadget)
  854. /*S*/
  855. {
  856.   TRACE("Entry");
  857.  
  858.   // neuen Balken erzeugen
  859.   BarWindowNodeC *poNode = new BarWindowNodeC(this, arg_sName, arg_sButtonName, arg_sScreenName, arg_bCloseGadget);
  860.   if (!poNode)
  861.   {
  862.     TRACE("Kein Speicher");
  863.     return FALSE;
  864.   } // if
  865.  
  866. return poNode;
  867. }
  868. /*E*/
  869. BarWindowNodeC *BarWindowListC::findBarWindowNode(ULONG arg_ulBarWindowID)
  870. /*S*/
  871. {
  872.   TRACE("Entry");
  873.   BarWindowNodeC *pNode = NULL;
  874.  
  875.   // wenn die Balkenliste nicht leer ist
  876.   if (!IsListEmpty(this))
  877.   {
  878.     pNode = (BarWindowNodeC *) lh_Head;
  879.     do
  880.     {
  881.       if (pNode->m_ulBarWindowID == arg_ulBarWindowID)
  882.       {
  883.         return pNode;
  884.       } // if
  885.     } while (pNode = pNode->getNext());
  886.   } // if
  887.  
  888. return pNode;
  889. }
  890. /*E*/
  891. int BarWindowListC::indexOf(BarWindowNodeC *arg_pNode)
  892. /*S*/
  893. {
  894.   TRACE("Entry");
  895.  
  896.   // wenn die Balkenliste nicht leer ist
  897.   if (arg_pNode && !IsListEmpty(this))
  898.   {
  899.     int iIndex = 0;
  900.  
  901.     // hole 1. eintrag
  902.     BarWindowNodeC *pNode = (BarWindowNodeC *) lh_Head;
  903.     do
  904.     {
  905.       // wenn gefunden
  906.       if (pNode==arg_pNode)
  907.       {
  908.         return iIndex;
  909.       } // if
  910.  
  911.       iIndex++;
  912.     } while (pNode = pNode->getNext());
  913.   } // if
  914.  
  915. return -1;
  916. }
  917. /*E*/
  918. BarWindowNodeC *BarWindowListC::operator[](int arg_iIndex)
  919. /*S*/
  920. {
  921.   TRACE("ENTRY");
  922.  
  923.   BarWindowNodeC *pNode = NULL;
  924.  
  925.   // wenn die Balken nicht leer ist
  926.   if (!IsListEmpty(this))
  927.   {
  928.     int index = 0;
  929.  
  930.     // hole 1. eintrag
  931.     pNode = (BarWindowNodeC *) lh_Head;
  932.     do
  933.     {
  934.       // wenn i.ten eintrag erreicht
  935.       if (index == arg_iIndex)
  936.       {
  937.         return pNode;
  938.       } // if
  939.  
  940.       index++;
  941.     } while (pNode = pNode->getNext());
  942.   } // if
  943.  
  944. return pNode;
  945. }
  946. /*E*/
  947. int BarWindowListC::getSize(void)
  948. /*S*/
  949. {
  950.   TRACE("Entry");
  951.   int iSize = 0;
  952.  
  953.   // wenn die Liste nicht leer ist
  954.   if (!IsListEmpty(this))
  955.   {
  956.     // hole 1. Eintrag
  957.     BarWindowNodeC *pNode = (BarWindowNodeC *) lh_Head;
  958.     for (iSize=1; pNode = pNode->getNext(); iSize++);
  959.   } // if
  960.  
  961. return iSize;
  962. }
  963. /*E*/
  964.  
  965.